import re

from django import http
from django.contrib.auth import login, authenticate, logout
from django.core.paginator import EmptyPage, Paginator
from django.shortcuts import render, redirect
from django.urls import reverse
from django.views import View
from django_redis import get_redis_connection

from apps.areas.models import Address
from apps.orders.models import OrderInfo
from apps.shoppingcart.utils import merge_cart_cookie_to_redis
from apps.user.models import User
from utils import constants
from utils.response_code import RETCODE
from django.contrib.auth.mixins import LoginRequiredMixin


class RegisterView(View):
    """注册类视图"""
    def get(self, request):
        return render(request, "register.html")

    def post(self, request):
        username = request.POST.get("username")  # 用户名
        password = request.POST.get("password")   # 密码
        password2 = request.POST.get("password2")  # 确认密码
        mobile = request.POST.get("mobile")   # 手机号码
        image_code = request.POST.get("image_code")  # verify
        allow = request.POST.get("allow")   # 是否勾选选项
        sms_code = request.POST.get("sms_code")
        print(password)

        if not all([username, password, mobile]):
            return http.HttpResponse("缺少参数")

        # if not re.match(r"^[0-9a-zA-Z]{5,20}$", username):
        #     return http.HttpResponse("请输入5-20个字符的用户名")

        if not re.match(r"^[0-9a-zA-Z]{8,20}$", password):
            return http.HttpResponse("请输入8-20位的密码")

        # 判断两次密码是否一致
        if password != password2:
            return http.HttpResponseBadRequest('两次输入的密码不一致')
        # 判断手机号是否合法
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseBadRequest('请输入正确的手机号码')

        # redis数据库连接
        redis_coon = get_redis_connection("code")

        sms_code_save = redis_coon.get("sms_%s" % mobile)

        if sms_code is None:
            return render(request, "register.html", {"sms_code_errmsg": "无效的验证码"})
        if sms_code != sms_code_save.decode():
            print(sms_code_save)
            return render(request, "register.html", {"sms_code_errmsg": "验证码有误"})

        # 保存数据
        try:
            # create_user 加密密码
            user = User.objects.create_user(username=username, password=password, mobile=mobile)
        except:
            return render(request, "register.html", {'register_errmsg': '注册失败'})

        # 注册成功后，实现状态保持
        login(request, user)

        # 然后重定向
        return redirect(reverse("index:index"))


class UsernameCountView(View):
    """判断用户名是否重复注册"""

    def get(self, request, username):
        """
        :param request: 请求对象
        :param username: 用户名
        :return: JSON
        """
        count = User.objects.filter(username=username).count()
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'count': count})


class MobileCountView(View):
    """判断手机号码是否重复"""

    def get(self, request, mobile):
        """

        :param request:
        :param mobile:
        :return:
        """
        mobile_count = User.objects.filter(mobile=mobile).count()
        return http.JsonResponse({"code": RETCODE.OK, "errmsg": "OK", "count": mobile_count})


class LoginView(View):
    """登录类视图"""
    def get(self, request):
        return render(request, "login.html")

    def post(self, request):
        username = request.POST.get("username")
        password = request.POST.get("password")
        remembered = request.POST.get('remembered')

        print(username, password)

        # 数据校验
        if not re.match(r"^[0-9a-zA-Z]{5,20}$", username):
            return render(request, "login.html", {"account_errmsg": "请输入5-20个字符的用户名"})
        # password 加密判断
        user = authenticate(username=username, password=password)
        if user is None:
            return render(request, "login.html", {"account_errmsg": "用户名或密码错误"})

        # 状态保持
        login(request, user)
        # 设置状态保持的周期
        if remembered != 'on':
            # 没有记住用户：浏览器会话结束就过期
            request.session.set_expiry(0)
        else:
            # 记住用户：None表示两周后过期
            request.session.set_expiry(None)

        # 响应登录结果
        next = request.GET.get('next')
        print(next)
        if next:
            response = redirect(next)
        else:
            response = redirect(reverse('index:index'))

        response.set_cookie("username", user.username, max_age=3600 * 24 * 15)

        response = merge_cart_cookie_to_redis(request=request, user=user, response=response)

        return response


class LogoutView(View):
    """退出登录"""

    def get(self, request):
        """实现退出登录逻辑"""
        # 清理session
        logout(request)

        # 退出登录，重定向到登录页
        response = redirect(reverse('index:index'))

        # 退出登录时清除cookie中的username
        response.delete_cookie('username')

        return response


class PasswordView(View):
    def get(self, request):
        """展示修改密码界面"""
        return render(request, 'base_center_pass.html')

    def post(self, request):
        """实现修改密码逻辑"""
        # 1.接收参数
        old_password = request.POST.get('old_password')
        new_password = request.POST.get('new_password')
        new_password2 = request.POST.get('new_password2')
        # 2.验证参数
        if not all([old_password, new_password, new_password2]):
            return http.HttpResponseForbidden('缺少必传参数')
        if not re.match(r'^[0-9A-Za-z]{8,20}$', new_password):
            return http.HttpResponseBadRequest('密码最少8位，最长20位')
        if new_password != new_password2:
            return http.HttpResponseBadRequest('两次输入的密码不一致')

        # 3.检验旧密码是否正确
        if not request.user.check_password(old_password):
            return render(request, 'user_center_pass.html', {'origin_password_errmsg':'原始密码错误'})
        # 4.更新新密码
        try:
            request.user.set_password(new_password)
            request.user.save()
        except Exception as e:
            return render(request, 'user_center_pass.html', {'change_password_errmsg': '修改密码失败'})
        # 5.退出登陆,删除登陆信息
        logout(request)
        # 6.跳转到登陆页面
        response = redirect(reverse('user:login'))

        response.delete_cookie('username')

        return response


class UserCenter(LoginRequiredMixin, View):
    """用户中心"""
    def get(self, request):
        context = {
            "username":request.user.username,
            "mobile": request.user.mobile,
            "email": request.user.email,
            "email_active": request.user.email_active
        }
        return render(request, "base_usercent.html", context=context)


class AddressView(LoginRequiredMixin, View):
    """收货地址"""
    def get(self, request):
        """提供收货地址界面"""
        # 获取用户地址列表
        addresses = Address.objects.filter(user=request.user, is_deleted=False)
        print(addresses)

        address_dict_list = []
        for address in addresses:
            address_dict = {
                "id": address.id,
                "title": address.title,
                "receiver": address.receiver,
                "province": address.province.name,
                "province_id": address.province_id,
                "city": address.city.name,
                "city_id": address.city_id,
                "district": address.district.name,
                "district_id": address.district_id,
                "place": address.place,
                "mobile": address.mobile,
                "tel": address.tel,
                "email": address.email
            }
            address_dict_list.append(address_dict)

        context = {
            'default_address_id': request.user.default_address_id,
            'addresses': address_dict_list,
        }

        return render(request, 'base_usercent_site.html', context)


class UserOrderView(View):
    """用户订单"""

    def get(self, request, page_num):
        """提供我的订单页面"""
        user = request.user
        # 查询订单
        orders = user.orderinfo_set.all().order_by("-create_time")
        # 遍历所有订单
        for order in orders:
            # 绑定订单状态
            order.status_name = OrderInfo.ORDER_STATUS_CHOICES[order.status-1][1]
            # 绑定支付方式
            order.pay_method_name = OrderInfo.PAY_METHOD_CHOICES[order.pay_method-1][1]
            order.sku_list = []
            # 查询订单商品
            order_goods = order.skus.all()
            # 遍历订单商品
            for order_good in order_goods:
                sku = order_good.sku
                sku.count = order_good.count
                sku.amount = sku.price * sku.count
                order.sku_list.append(sku)

        # 分页
        page_num = int(page_num)
        try:
            paginator = Paginator(orders, constants.ORDERS_LIST_LIMIT)
            page_orders = paginator.page(page_num)
            total_page = paginator.num_pages
        except EmptyPage:
            return http.HttpResponseNotFound('订单不存在')

        context = {
            "page_orders": page_orders,
            'total_page': total_page,
            'page_num': page_num,
        }
        return render(request, "user_center_order.html", context)
